package encryption;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * AES加解密
 */
public class AesEncryption {
    /**
     * 算法
     */
    private static final String ALGORITHM = "AES";

    /**
     * 加密解密算法/加密模式/填充方式
     */
    private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";

    /**
     * 加密
     *
     * @param content 要加密的明文
     * @param key     加密key
     * @param keyVi   加密key向量
     * @return 密文
     */
    public static String encode(String content, String key, String keyVi) {
        String result = null;

        if (content == null || content.isEmpty()) {
            throw new IllegalArgumentException("content");
        }

        if (key == null || key.isEmpty()) {
            throw new IllegalArgumentException("key");
        }

        if (keyVi == null || keyVi.isEmpty()) {
            throw new IllegalArgumentException("keyVi");
        }

        try {
            var secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM);
            var cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(keyVi.getBytes()));

            var encodedBytes = content.getBytes(StandardCharsets.UTF_8);
            var encodedAesBytes = cipher.doFinal(encodedBytes);

            var base64Encoder = Base64.getEncoder();
            result = base64Encoder.encodeToString(encodedAesBytes);
        } catch (Throwable ignored) {

        }

        return result;
    }

    /**
     * 解密
     *
     * @param content 要加密的明文
     * @param key     加密key
     * @param keyVi   加密key向量
     * @return 解密后的原文
     */
    public static String decode(String content, String key, String keyVi) {
        String result = null;

        if (content == null || content.isEmpty()) {
            throw new IllegalArgumentException("content");
        }

        if (key == null || key.isEmpty()) {
            throw new IllegalArgumentException("key");
        }

        if (keyVi == null || keyVi.isEmpty()) {
            throw new IllegalArgumentException("keyVi");
        }

        try {
            var secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM);
            var cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(keyVi.getBytes()));

            var base64Decoder = Base64.getDecoder();
            var decodedBase64Bytes = base64Decoder.decode(content);
            var decodedBytes = cipher.doFinal(decodedBase64Bytes);

            result = new String(decodedBytes, StandardCharsets.UTF_8);
        } catch (Throwable ignored) {

        }

        return result;
    }
}
